package br.com.vti.leilao.view.util;

import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

/**
 * Classe responsavel pelo tratamento das mensagens do sistema.
 *
 * @author Ednardo Rubens
 *
 */
@Component("messageFactory")
public class MessageFactoryImpl implements MessageFactory {

    private static final long serialVersionUID = -4283846366089071251L;
    public transient static final Logger logger = Logger.getLogger(MessageFactoryImpl.class);

    public FacesContext getFacesContext() {
        return FacesContext.getCurrentInstance();
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#getApplicationBundle()
     */
    @Override
    public ResourceBundle getApplicationBundle() {
        ResourceBundle rb = null;
        if (getFacesContext() != null
                && getFacesContext().getApplication() != null
                && getFacesContext().getApplication().getMessageBundle() != null) {
            rb = getBundle(getFacesContext().getApplication().getMessageBundle());
        }
        return rb;
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#getBundle(java.lang.String)
     */
    @Override
    public ResourceBundle getBundle(String nome) {
        ResourceBundle rb = null;
        Locale locale = new Locale("pt_BR");
        if (getFacesContext() != null
                && getFacesContext().getViewRoot() != null
                && getFacesContext().getViewRoot().getLocale() != null) {
            locale = getFacesContext().getViewRoot().getLocale();
        }
        if (nome != null && !nome.isEmpty()) {
            rb = ResourceBundle.getBundle(nome, locale);
        }
        return rb;
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#isMessageErro()
     */
    @Override
    public boolean isMessageErro() {
        List<FacesMessage> lista = getFacesContext().getMessageList();
        boolean retorno = Boolean.FALSE;
        for (FacesMessage facesMessage : lista) {
            if (facesMessage.getSeverity() == FacesMessage.SEVERITY_ERROR) {
                retorno = Boolean.TRUE;
            }
        }
        return retorno;
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#addMessage(java.lang.String, java.lang.String, int)
     */
    @Override
    public void addMessage(String clientId, String msg, int codErro) {
        Severity severity = null;
        switch (codErro) {
            case SEVERITY_INFO:
                severity = FacesMessage.SEVERITY_INFO;
                break;
            case SEVERITY_WARN:
                severity = FacesMessage.SEVERITY_WARN;
                break;
            case SEVERITY_ERROR:
                severity = FacesMessage.SEVERITY_ERROR;
                break;
            case SEVERITY_FATAL:
                severity = FacesMessage.SEVERITY_FATAL;
                break;
            default:
                break;
        }
        getFacesContext().addMessage(clientId,
                new FacesMessage(severity, msg, msg));
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#addInfoMessage(java.lang.String)
     */
    @Override
    public void addInfoMessage(String msg) {
        addMessage(null, msg, SEVERITY_INFO);
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#addErrorMessage(java.lang.String)
     */
    @Override
    public void addErrorMessage(String msg) {
        addMessage(null, msg, SEVERITY_ERROR);
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#addWarnMessage(java.lang.String)
     */
    @Override
    public void addWarnMessage(String msg) {
        addMessage(null, msg, SEVERITY_WARN);
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#addFatalMessage(java.lang.String)
     */
    @Override
    public void addFatalMessage(String msg) {
        addMessage(null, msg, SEVERITY_FATAL);
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#getMessage(java.lang.String, java.lang.Object)
     */
    @Override
    public String getMessage(String key, Object... parametros) {
        String msg = null;
        try {
            List<ResourceBundle> bundles = new LinkedList<ResourceBundle>();
            bundles.add(getApplicationBundle());
            for (ResourceBundle rb : bundles) {
                String msgAux = getMessageRb(rb, key, parametros);
                if (msgAux != null && !msgAux.isEmpty()) {
                    msg = msgAux;
                }
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return msg;
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#getMessage(java.util.ResourceBundle rb, java.lang.String, java.lang.Object)
     */
    @Override
    public String getMessageRb(ResourceBundle rb, String key, Object... parametros) {
        String msg = null;
        try {
            if (rb != null && rb.containsKey(key)) {
                msg = rb.getString(key);
            }
            if (msg != null && parametros.length > 0) {
                msg = MessageFormat.format(msg, parametros);
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return msg;
    }

    /* (non-Javadoc)
     * @see br.com.vti.core.view.util.MessageFactory#getValidationMessage(java.lang.String)
     */
    @Override
    public String getValidationMessage(String key) {
        String msg = null;
        if (key != null && !key.isEmpty()) {
            Properties props = new Properties();
            try {
                InputStream is = getClass().getResourceAsStream("/ValidationMessages.properties");
                props.load(is);
                is.close();
            } catch (IOException ex) {
                logger.error(ex);
            }
            msg = props.getProperty(key);
        }
        return msg;
    }
}